#ifndef _S2N_H
#define _S2N_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <string.h>

#define U16_TRAN_CHAR_0(p) (((p)&0xff00) >> 8)
#define U16_TRAN_CHAR_1(p) ((p)&0x00ff)

#define U32_TRAN_CHAR_0(p) (((p) >> 24) & 0xff)
#define U32_TRAN_CHAR_1(p) (((p) >> 16) & 0xff)
#define U32_TRAN_CHAR_2(p) (((p) >> 8) & 0xff)
#define U32_TRAN_CHAR_3(p) ((p)&0xff)

// s2n
#define S2N_STRUCT_GET_uint8_t_ELEMENT(to_netbuf, from_struct, _element)                                               \
    *(uint8_t *)to_netbuf = (from_struct)->_element;                                                                   \
    to_netbuf += sizeof(char);

#define S2N_STRUCT_GET_uint16_t_ELEMENT(to_netbuf, from_struct, _element)                                              \
    *(uint8_t *)to_netbuf = U16_TRAN_CHAR_0((from_struct)->_element);                                                  \
    *(uint8_t *)(to_netbuf + 1) = U16_TRAN_CHAR_1((from_struct)->_element);                                            \
    to_netbuf += sizeof(int16_t);

#define S2N_STRUCT_GET_uint32_t_ELEMENT(to_netbuf, from_struct, _element)                                              \
    *(uint8_t *)to_netbuf = U32_TRAN_CHAR_0((from_struct)->_element);                                                  \
    *(uint8_t *)(to_netbuf + 1) = U32_TRAN_CHAR_1((from_struct)->_element);                                            \
    *(uint8_t *)(to_netbuf + 2) = U32_TRAN_CHAR_2((from_struct)->_element);                                            \
    *(uint8_t *)(to_netbuf + 3) = U32_TRAN_CHAR_3((from_struct)->_element);                                            \
    to_netbuf += sizeof(int32_t);

#define S2N_STRUCT_GET_string_ELEMENT(to_netbuf, from_struct, _element)                                                \
    memmove(to_netbuf, (from_struct)->_element, sizeof((from_struct)->_element));                                      \
    to_netbuf += sizeof((from_struct)->_element);

#define S2N_STRUCT_GET_BASIC_ELEMENT(to_netbuf, from_struct, type, _element)                                           \
    S2N_STRUCT_GET_##type##_ELEMENT(to_netbuf, from_struct, _element)

// function
/* structure object to netbuf */
#define s2n_struct_get_basic_element(to_netbuf, from_struct, type, element)                                            \
    S2N_STRUCT_GET_BASIC_ELEMENT(to_netbuf, from_struct, type, element)

#ifdef __cplusplus
}
#endif

#endif
